package core.net
{
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import core.managers.SWFManager;
	
	/**
	 * 字节流加载器，加载完成之后会讲加载到的二进制数据缓存到SWFManager<br/>
	 *  
	 * @example
	 * <listing>
	 * 
	 * 	var loader:BinaryLoader = new BinaryLoader();
	 * 	//method 1: recommanded, use loader directly.
	 * 	loader.loadSwf(1,"xxx.swf");
	 * 
	 * 	//method 2: not recommanded due to performance, use loader.content...
	 * 	loader.loadSwf(1,"xxx.swf", callBack);
	 * 
	 * 	function callBack(content:DisplayObject):void{
	 * 		whatever.addChild(content);
	 * 	}
	 * </listing>
	 * @author Ado
	 * @see core.managers.SWFManager
	 */
	public class BinaryLoader extends Sprite
	{
		/** 加载器 */
		private var uLoader:URLLoader;
		/** 转换器 */
		private var switcher:Loader;
		/** id */
		private var id:int;
		/** 回调函数 */
		private var callBack:Function;
		private var needCached:Boolean;
		public function BinaryLoader()
		{
			this.buttonMode = true;
		}
		/**
		 *  获取swf，如果已经缓存起来可直接拿取，否则会进行加载流程
		 * @param _id	需要加载的swf的唯一标识
		 * @param url	需要加载的swf的url
		 * @param needCached 是否需要缓存
		 * @param cb	加载完成后是否有回调函数，没有回调函数的话默认添加到本实例容器，有的话作为回调函数的参数返回
		 * 
		 */		
		public function loadSwf(_id:int, url:String, _needCached:Boolean=true, cb:Function=null):void
		{
			id = _id;
			callBack = cb;
			needCached = _needCached;
			if(SWFManager.hasSwf(_id))
			{
				var ba:ByteArray = SWFManager.getSwf(_id);
				startSwitch(ba);
			}else
			{
				uLoader = new URLLoader();
				uLoader.dataFormat = URLLoaderDataFormat.BINARY;
				uLoader.addEventListener(Event.COMPLETE, loadComplete);
				uLoader.addEventListener(IOErrorEvent.IO_ERROR, onError);
				uLoader.addEventListener(ProgressEvent.PROGRESS, loadProgress);
				uLoader.load(new URLRequest(url+"?version="+Math.random()*100));
			}
		}
		/** 开始转换 */
		private function startSwitch(ba:ByteArray):void
		{
			switcher = new Loader();
			switcher.contentLoaderInfo.addEventListener(Event.COMPLETE, switchComplete);
			switcher.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
			ba.position=0;
			switcher.loadBytes(ba);
		}
		/** 转换完成 */
		private function switchComplete(e:Event):void
		{
			switcher.contentLoaderInfo.removeEventListener(Event.COMPLETE, switchComplete);
			switcher.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			if(callBack != null)
			{
				callBack.apply(null,[switcher, name]);
//				callBack(switcher,name);
			}else
			{
				addChild(switcher);
			}
		}
		/** 二进制数据加载完成 */
		private function loadComplete(e:Event):void
		{
			if(needCached)
			{
				SWFManager.addSwf(id, uLoader.data);
			}
			startSwitch(SWFManager.getSwf(id));
			uLoader.removeEventListener(Event.COMPLETE, loadComplete);
			uLoader.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			uLoader.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
		}
		/** 加载或者转换失败 */
		private function onError(e:IOErrorEvent):void
		{
			if(e.target is URLLoader)
			{
				uLoader.removeEventListener(Event.COMPLETE, loadComplete);
				uLoader.removeEventListener(IOErrorEvent.IO_ERROR, onError);
				uLoader.removeEventListener(ProgressEvent.PROGRESS, loadProgress);
			}else{
				switcher.contentLoaderInfo.removeEventListener(Event.COMPLETE, switchComplete);
				switcher.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR, onError);
			}
		}
		/** 加载或者转换进度 */
		private function loadProgress(e:ProgressEvent):void
		{
			trace(e.bytesLoaded/e.bytesTotal*100+"%...");
		}
	}
}